package cn.kimming.wms.service.impl;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import cn.kimming.wms.anno.RequiredPermission;
import cn.kimming.wms.dao.IPermissionDAO;
import cn.kimming.wms.domain.Permission;
import cn.kimming.wms.query.QueryObject;
import cn.kimming.wms.service.IPermissionService;
import cn.kimming.wms.util.PermissionUtils;
import cn.kimming.wms.web.action.BaseAction;

@Service("permissionService")
public class PermissionServiceImpl implements IPermissionService {

	@Autowired
	private IPermissionDAO permissionDAO;
	@Autowired
	private ApplicationContext ctx;
	
	@Override
	public void save(Permission p) {
		permissionDAO.save(p);
	}

	@Override
	public void update(Permission p) {
		permissionDAO.update(p);
	}

	@Override
	public void delete(Long id) {
		permissionDAO.delete(permissionDAO.get(id));
	}

	@Override
	public Permission get(Long id) {
		return permissionDAO.get(id);
	}

	@Override
	public List<Permission> list() {
		return permissionDAO.list();
	}
	
	@Override
	public List<Permission> query(QueryObject qo) {
		return permissionDAO.query(qo);
	}

	@Override
	public void load() {
		// 1.获取数据库中原有权限列表
		List<Permission> permissions = permissionDAO.list();
		Set<String> exps = new HashSet<>();
		for (Permission p : permissions) {
			exps.add(p.getExpression());
		}
		// 2.扫描BaseAction所有子类actions
		Map<String, BaseAction> beansMap = ctx.getBeansOfType(BaseAction.class);
		// 3.迭代actions,获取其中的方法methods
		for (BaseAction action : beansMap.values()) {
			Method[] mds = action.getClass().getDeclaredMethods();
			// 4.迭代methods,判断方法上是否带有权限标签
			for (Method md : mds) {
				RequiredPermission rp = md.getAnnotation(RequiredPermission.class);
				String exp = PermissionUtils.buildExpression(md);
				if (rp != null && !exps.contains(exp)) {
					// 5.若有,创建权限对象并保存
					Permission p = new Permission();
					p.setName(rp.value());
					p.setExpression(exp);
					permissionDAO.save(p);
				}
			}
		}
	}


}
